package com.approval.service;

import com.approval.dto.*;
import com.approval.entity.*;
import com.approval.exception.BusinessException;
import com.approval.mapper.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色管理服务
 */
@Service
@Transactional
public class RoleService {
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    @Autowired
    private PermissionMapper permissionMapper;
    
    /**
     * 创建角色
     */
    public RoleResponse createRole(RoleCreateRequest request) {
        // 验证角色编码是否已存在
        if (roleMapper.selectByRoleCode(request.getRoleCode()) != null) {
            throw new BusinessException("角色编码已存在");
        }
        
        Role role = new Role();
        BeanUtils.copyProperties(request, role);
        role.setCreateTime(new Date());
        role.setUpdateTime(new Date());
        roleMapper.insert(role);
        
        // 分配权限
        if (request.getPermissionIds() != null && !request.getPermissionIds().isEmpty()) {
            assignPermissionsToRole(role.getId(), request.getPermissionIds());
        }
        
        return convertToRoleResponse(role);
    }
    
    /**
     * 更新角色
     */
    public RoleResponse updateRole(Long roleId, RoleUpdateRequest request) {
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        // 验证角色编码是否已被其他角色使用
        if (request.getRoleCode() != null && !request.getRoleCode().equals(role.getRoleCode()) &&
            roleMapper.existsByRoleCodeAndIdNot(request.getRoleCode(), roleId)) {
            throw new BusinessException("角色编码 '" + request.getRoleCode() + "' 已被其他角色使用，请使用其他编码");
        }
        
        BeanUtils.copyProperties(request, role, "id", "createTime");
        role.setUpdateTime(new Date());
        roleMapper.update(role);
        
        // 更新权限
        if (request.getPermissionIds() != null) {
            updateRolePermissions(roleId, request.getPermissionIds());
        }
        
        return convertToRoleResponse(role);
    }
    
    /**
     * 删除角色
     */
    public void deleteRole(Long roleId) {
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        // 检查是否为系统角色
        if ("system".equals(role.getRoleType())) {
            throw new BusinessException("不能删除系统角色");
        }
        
        // 检查是否有用户使用该角色
        if (userRoleMapper.countByRoleId(roleId) > 0) {
            throw new BusinessException("该角色下还有用户，不能删除");
        }
        
        roleMapper.deleteById(roleId);
    }
    
    /**
     * 根据ID获取角色
     */
    public RoleResponse getRoleById(Long roleId) {
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        return convertToRoleResponse(role);
    }
    
    /**
     * 分页查询角色
     */
    public PageResponse<RoleResponse> getRoles(PageRequestDto pageRequest, String roleName, String roleType, Integer status) {
        int offset = (pageRequest.getPage() - 1) * pageRequest.getSize();
        List<Role> roles = roleMapper.selectWithConditions(roleName, roleType, status, offset, pageRequest.getSize());
        long total = roleMapper.countWithConditions(roleName, roleType, status);
        
        List<RoleResponse> roleResponses = roles.stream()
            .map(this::convertToRoleResponse)
            .collect(Collectors.toList());
        
        return new PageResponse<>(roleResponses, pageRequest.getPage(), pageRequest.getSize(), total);
    }
    
    /**
     * 获取所有角色
     */
    public List<RoleResponse> getAllRoles() {
        List<Role> roles = roleMapper.selectAll();
        return roles.stream()
            .map(this::convertToRoleResponse)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取角色树
     */
    public List<RoleResponse> getRoleTree() {
        List<Role> roles = roleMapper.selectAll();
        return buildRoleTree(roles);
    }
    
    /**
     * 获取角色权限预览
     */
    public RolePermissionPreviewResponse getRolePermissionPreview(Long roleId) {
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        List<Permission> allPermissions = permissionMapper.selectByRoleId(roleId);
        
        List<PermissionResponse> menuPermissions = allPermissions.stream()
            .filter(p -> "menu".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<PermissionResponse> operationPermissions = allPermissions.stream()
            .filter(p -> "operation".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<PermissionResponse> dataPermissions = allPermissions.stream()
            .filter(p -> "data".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<String> allPermissionCodes = allPermissions.stream()
            .map(Permission::getPermissionCode)
            .collect(Collectors.toList());
        
        RolePermissionPreviewResponse response = new RolePermissionPreviewResponse();
        response.setRoleId(role.getId());
        response.setRoleName(role.getRoleName());
        response.setRoleCode(role.getRoleCode());
        response.setUserCount(userRoleMapper.countByRoleId(roleId));
        response.setMenuPermissions(menuPermissions);
        response.setOperationPermissions(operationPermissions);
        response.setDataPermissions(dataPermissions);
        response.setAllPermissions(allPermissionCodes);
        
        return response;
    }
    
    /**
     * 为用户分配角色
     */
    public void assignRolesToUser(UserRoleAssignRequest request) {
        // 删除现有角色
        userRoleMapper.deleteByUserId(request.getUserId());
        
        // 分配新角色
        if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
            for (Long roleId : request.getRoleIds()) {
                Role role = roleMapper.selectById(roleId);
                if (role == null) {
                    throw new BusinessException("角色不存在: " + roleId);
                }
                
                UserRole userRole = new UserRole();
                userRole.setUserId(request.getUserId());
                userRole.setRoleId(roleId);
                userRole.setCreateTime(new Date());
                userRoleMapper.insert(userRole);
            }
        }
    }
    
    /**
     * 为角色分配权限
     */
    public void assignPermissionsToRole(RolePermissionAssignRequest request) {
        // 删除现有权限
        rolePermissionMapper.deleteByRoleId(request.getRoleId());
        
        // 分配新权限
        if (request.getPermissionIds() != null && !request.getPermissionIds().isEmpty()) {
            for (Long permissionId : request.getPermissionIds()) {
                Permission permission = permissionMapper.selectById(permissionId);
                if (permission == null) {
                    throw new BusinessException("权限不存在: " + permissionId);
                }
                
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(request.getRoleId());
                rolePermission.setPermissionId(permissionId);
                rolePermission.setCreateTime(new Date());
                rolePermissionMapper.insert(rolePermission);
            }
        }
    }
    
    // 私有方法
    
    private void assignPermissionsToRole(Long roleId, List<Long> permissionIds) {
        // 删除现有权限
        rolePermissionMapper.deleteByRoleId(roleId);
        
        // 分配新权限
        for (Long permissionId : permissionIds) {
            Permission permission = permissionMapper.selectById(permissionId);
            if (permission == null) {
                throw new BusinessException("权限不存在: " + permissionId);
            }
            
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermission.setCreateTime(new Date());
            rolePermissionMapper.insert(rolePermission);
        }
    }
    
    private void updateRolePermissions(Long roleId, List<Long> permissionIds) {
        if (permissionIds.isEmpty()) {
            rolePermissionMapper.deleteByRoleId(roleId);
        } else {
            assignPermissionsToRole(roleId, permissionIds);
        }
    }
    
    private RoleResponse convertToRoleResponse(Role role) {
        RoleResponse response = new RoleResponse();
        BeanUtils.copyProperties(role, response);
        
        // 设置父角色名称
        if (role.getParentId() != null) {
            Role parentRole = roleMapper.selectById(role.getParentId());
            if (parentRole != null) {
                response.setParentRoleName(parentRole.getRoleName());
            }
        }
        
        // 设置用户数量
        response.setUserCount(userRoleMapper.countByRoleId(role.getId()));
        
        return response;
    }
    
    private PermissionResponse convertToPermissionResponse(Permission permission) {
        PermissionResponse response = new PermissionResponse();
        BeanUtils.copyProperties(permission, response);
        
        // 设置父权限名称
        if (permission.getParentId() != null) {
            Permission parentPermission = permissionMapper.selectById(permission.getParentId());
            if (parentPermission != null) {
                response.setParentPermissionName(parentPermission.getPermissionName());
            }
        }
        
        // 设置角色数量
        response.setRoleCount(rolePermissionMapper.countByPermissionId(permission.getId()));
        
        return response;
    }
    
    /**
     * 构建角色树
     */
    private List<RoleResponse> buildRoleTree(List<Role> roles) {
        // 转换为RoleResponse
        List<RoleResponse> roleResponses = roles.stream()
            .map(this::convertToRoleResponse)
            .collect(Collectors.toList());
        
        // 构建父子关系映射
        Map<Long, List<RoleResponse>> childrenMap = new HashMap<>();
        List<RoleResponse> rootRoles = new ArrayList<>();
        
        for (RoleResponse role : roleResponses) {
            if (role.getParentId() == null) {
                rootRoles.add(role);
            } else {
                childrenMap.computeIfAbsent(role.getParentId(), k -> new ArrayList<>()).add(role);
            }
        }
        
        // 递归设置子角色
        for (RoleResponse rootRole : rootRoles) {
            setChildren(rootRole, childrenMap);
        }
        
        return rootRoles;
    }
    
    /**
     * 递归设置子角色
     */
    private void setChildren(RoleResponse role, Map<Long, List<RoleResponse>> childrenMap) {
        List<RoleResponse> children = childrenMap.get(role.getId());
        if (children != null && !children.isEmpty()) {
            role.setChildren(children);
            for (RoleResponse child : children) {
                setChildren(child, childrenMap);
            }
        }
    }
    
    /**
     * 获取角色的用户列表
     */
    public List<UserResponse> getRoleUsers(Long roleId) {
        List<User> users = userRoleMapper.selectUsersByRoleId(roleId);
        return users.stream()
            .map(this::convertToUserResponse)
            .collect(Collectors.toList());
    }
    
    private UserResponse convertToUserResponse(User user) {
        UserResponse response = new UserResponse();
        BeanUtils.copyProperties(user, response);
        return response;
    }
}